/*******************************************************************************
 * Copyright (c) 2012, 2013 XML-Print Project.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     XML-Print Project - initial API and implementation
 ******************************************************************************/
package info.xmlprint.core.xml;

import info.xmlprint.core.format.Format;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/*
 * Ein PElement enhaelte alle Attribute und Werte ein Elemenent aus originale XML, 
 */
public class PElement implements Serializable {
	private static final long serialVersionUID = 5011745867294649115L;

	private Map<String, PAttribut> attrMap = new HashMap<String, PAttribut>();
	private List<String> list = new ArrayList<String>();

	private Map<String, PElement> childrenMap;
	private String name;
	private PElement parentElement;

	private Format format;

	public PElement(String name) {
		this.name = name;
	}

	// clone
	public PElement clone() {
		PElement pe = new PElement(new String(this.name));

		List<String> cloneList = new ArrayList<String>();

		// attriMap
		Map<String, PAttribut> cloneAttrMap = new HashMap<String, PAttribut>();
		Iterator<Entry<String, PAttribut>> it = attrMap.entrySet().iterator();
		while (it.hasNext()) {
			String attrName = it.next().getKey();
			PAttribut pa = attrMap.get(attrName).clone();
			cloneAttrMap.put(attrName, pa);
			cloneList.add(attrName);
		}
		pe.setAttrMap(cloneAttrMap);
		pe.setList(cloneList);

		// childrenMap
		if (childrenCount() > 0) {
			Map<String, PElement> chMap = new HashMap<String, PElement>();
			for (PElement ch : getChildrens()) {
				chMap.put(new String(ch.getName()), ch.clone());
			}
		}

		if (this.parentElement != null)
			pe.setParentElement(this.parentElement.clone());
		if (this.format != null)
			pe.setFormat(format.objClone());
		return pe;
	}

	private void setAttrMap(Map<String, PAttribut> map) {
		this.attrMap = map;
	}

	public void setList(List<String> list) {
		this.list = list;
	}

	public void setChildrenMap(Map<String, PElement> map) {
		this.childrenMap = map;
	}

	public void setParentElement(PElement pe) {
		this.parentElement = pe;
		pe.addChildren(this.name, this);
	}

	// clone end

	public void setFormat(Format format) {
		this.format = format;
	}

	public Format getFormat() {
		return this.format;
	}

	public PElement(PElement parentElement, String name) {
		this.name = name;
		this.parentElement = parentElement;
	}

	public List<String> getAttributList() {
		return list;
	}

	public void addChildren(String name) {
		if (childrenMap == null)
			childrenMap = new HashMap<String, PElement>();

		childrenMap.put(name, new PElement(this, name));
	}

	public void addChildren(String name, PElement pe) {
		if (childrenMap == null)
			childrenMap = new HashMap<String, PElement>();

		childrenMap.put(name, pe);
	}

	public PElement getChildren(String name) {
		return childrenMap.get(name);
	}

	public int childrenCount() {
		if (childrenMap == null)
			return -1;
		return childrenMap.size();
	}

	public PElement getParent() {
		return parentElement;
	}

	public PElement[] getChildrens() {
		if (childrenMap == null)
			return null;

		Iterator<Entry<String, PElement>> it = childrenMap.entrySet()
				.iterator();

		PElement[] elements = new PElement[this.childrenCount()];
		int i = 0;
		while (it.hasNext()) {
			elements[i] = it.next().getValue();
			i++;
		}
		return elements;
	}

	public void removeChildren(String cName) {
		childrenMap.remove(cName);
	}

	/*
	 * nur für Element mit Parent gilt.
	 */
	public void setName(String newName) {
		this.getParent().removeChildren(this.name);
		this.name = newName;
		this.getParent().addChildren(newName, this);
	}

	public String getName() {
		return this.name;
	}

	public void setChildrenName(String oldName, String newName) {
		this.getChildren(oldName).setName(newName);
	}

	public List<String> getValueList(String attriName) {
		PAttribut pa = attrMap.get(attriName);
		if (pa != null)
			return attrMap.get(attriName).getList();
		else
			return null;
	}

	public void addAttribut(String attriName, String value) {
		if (attriName == null || attriName.isEmpty()) {
			return;
//			attriName = "";
//			value = "";
		}
		if (!attrMap.containsKey(attriName)) {
			attrMap.put(attriName, new PAttribut(attriName));
			list.add(attriName);
		}

		attrMap.get(attriName).addValue(value);

	}

	public int getAttributCount() {
		return attrMap.size();
	}

	public PAttribut[] getAttributs() {
		Iterator<Entry<String, PAttribut>> it = attrMap.entrySet().iterator();

		PAttribut[] attributs = new PAttribut[this.attrMap.size()];
		int i = 0;
		while (it.hasNext()) {
			attributs[i] = it.next().getValue();
			i++;
		}
		return attributs;
	}
}
